/*
 * Copyright 2008 Zoundry LLC, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package org.zoundry.gaedt.core.models;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
import org.zoundry.gaedt.core.ZGaeException;


/**
 * A generic reader that uses Sax to read in an XML file and produce a
 * model.  This class is thread safe and reentrant.
 */
public class ZGaeSaxModelReader
{
    /** The model factory used to create the models. */
    private IZGaeModelFactory mModelFactory;
    /** Used to convert parsed attribute values into their correct type for setting on the model. */
    private IZGaeModelTypeMapper mTypeMapper;
    /** Used to find the mutator method to use when setting an attribute value on a model. */
    private IZGaeModelMutatorProvider mMutatorProvider;

    /**
     * C'tor.
     */
    /**
     * @param aModelFactory
     * @param aTypeMapper
     * @param aMutatorProvider
     */
    public ZGaeSaxModelReader(IZGaeModelFactory aModelFactory, IZGaeModelTypeMapper aTypeMapper,
            IZGaeModelMutatorProvider aMutatorProvider)
    {
        setModelFactory(aModelFactory);
        setTypeMapper(aTypeMapper);
        setMutatorProvider(aMutatorProvider);
    }
    
    /**
     * Read the model from the given input source.
     * 
     * @param aInputSource
     * @throws ZGaeException
     */
    public ZGaeModel read(InputSource aInputSource) throws ZGaeException
    {
        try
        {
            XMLReader reader = XMLReaderFactory.createXMLReader();
            ZGaeSaxModelHandler handler = createModelHandler();
            reader.setContentHandler(handler);
            reader.parse(aInputSource);
            return handler.getModel();
        }
        catch (Exception e)
        {
            throw new ZGaeException(e);
        }
    }

    /**
     * Creates the handler used to handle the sax parse and build a model.
     */
    protected ZGaeSaxModelHandler createModelHandler()
    {
        return new ZGaeSaxModelHandler(getModelFactory(), getTypeMapper(), getMutatorProvider());
    }

    /**
     * @return the modelFactory
     */
    protected IZGaeModelFactory getModelFactory()
    {
        return mModelFactory;
    }

    /**
     * @param aModelFactory the modelFactory to set
     */
    protected void setModelFactory(IZGaeModelFactory aModelFactory)
    {
        mModelFactory = aModelFactory;
    }

    /**
     * @return the typeMapper
     */
    protected IZGaeModelTypeMapper getTypeMapper()
    {
        return mTypeMapper;
    }

    /**
     * @param aTypeMapper the typeMapper to set
     */
    protected void setTypeMapper(IZGaeModelTypeMapper aTypeMapper)
    {
        mTypeMapper = aTypeMapper;
    }

    /**
     * @return the mutatorProvider
     */
    protected IZGaeModelMutatorProvider getMutatorProvider()
    {
        return mMutatorProvider;
    }

    /**
     * @param aMutatorProvider the mutatorProvider to set
     */
    protected void setMutatorProvider(IZGaeModelMutatorProvider aMutatorProvider)
    {
        mMutatorProvider = aMutatorProvider;
    }
}
